<!DOCTYPE html>
<html>
<head>
    <title>p-V Diagram</title>
</head>
<body>
<canvas id="physics-diagram" width="550" height="450"></canvas>
<script>
    const canvas = document.getElementById('physics-diagram');
    const ctx = canvas.getContext('2d');

    // Style settings
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.lineWidth = 2;
    ctx.font = 'italic 20px Times New Roman';

    // Helper function to draw an arrowhead at a point with a given angle
    function drawArrowhead(x, y, angle, size) {
        ctx.save();
        ctx.beginPath();
        ctx.translate(x, y);
        ctx.rotate(angle);
        ctx.moveTo(0, 0);
        ctx.lineTo(-size, -size / 2);
        ctx.moveTo(0, 0);
        ctx.lineTo(-size, size / 2);
        ctx.stroke();
        ctx.restore();
    }

    // --- Main Drawing ---

    // 1. Draw Coordinate System
    const origin = { x: 50, y: 400 };
    const pAxisEnd = { x: 50, y: 30 };
    const vAxisEnd = { x: 500, y: 400 };

    // p-axis
    ctx.beginPath();
    ctx.moveTo(origin.x, origin.y);
    ctx.lineTo(pAxisEnd.x, pAxisEnd.y);
    ctx.stroke();
    drawArrowhead(pAxisEnd.x, pAxisEnd.y, -Math.PI / 2, 10);

    // V-axis
    ctx.beginPath();
    ctx.moveTo(origin.x, origin.y);
    ctx.lineTo(vAxisEnd.x, vAxisEnd.y);
    ctx.stroke();
    drawArrowhead(vAxisEnd.x, vAxisEnd.y, 0, 10);

    // Axis labels
    ctx.fillText('p', pAxisEnd.x - 25, pAxisEnd.y + 10);
    ctx.fillText('V', vAxisEnd.x, vAxisEnd.y + 25);
    ctx.fillText('O', origin.x - 20, origin.y + 20);

    // 2. Define process points
    const a = { x: 120, y: 350 };
    const d = { x: 450, y: 350 };
    const b = { x: 450, y: 100 };
    const c = { x: 120, y: 100 };

    // 3. Draw the rectangular cycle (a -> d -> b -> c -> a)
    ctx.beginPath();
    ctx.moveTo(a.x, a.y);
    ctx.lineTo(d.x, d.y); // a -> d
    ctx.lineTo(b.x, b.y); // d -> b
    ctx.lineTo(c.x, c.y); // b -> c
    ctx.closePath();     // c -> a
    ctx.stroke();

    // Arrows for the rectangular cycle
    drawArrowhead((a.x + d.x) / 2, a.y, 0, 10);             // a -> d
    drawArrowhead(d.x, (d.y + b.y) / 2, -Math.PI / 2, 10);  // d -> b
    drawArrowhead((b.x + c.x) / 2, b.y, Math.PI, 10);       // b -> c
    drawArrowhead(c.x, (c.y + a.y) / 2, Math.PI / 2, 10);   // c -> a

    // 4. Draw the curved path (a -> b)
    const cp1 = { x: 150, y: 240 };
    const cp2 = { x: 400, y: 220 };
    ctx.beginPath();
    ctx.moveTo(a.x, a.y);
    ctx.bezierCurveTo(cp1.x, cp1.y, cp2.x, cp2.y, b.x, b.y);
    ctx.stroke();

    // Arrows for the curved path
    // Position 1 (approximated on the curve)
    const arrow1_pos = { x: 200, y: 268 };
    const arrow1_angle = -Math.PI / 3; // Approx -60 degrees
    drawArrowhead(arrow1_pos.x, arrow1_pos.y, arrow1_angle, 10);

    // Position 2 (approximated on the curve)
    const arrow2_pos = { x: 340, y: 160 };
    const arrow2_angle = -Math.PI / 5; // Approx -36 degrees
    drawArrowhead(arrow2_pos.x, arrow2_pos.y, arrow2_angle, 10);


    // 5. Draw point labels
    ctx.fillText('a', a.x - 20, a.y + 5);
    ctx.fillText('b', b.x + 5, b.y);
    ctx.fillText('c', c.x - 20, c.y);
    ctx.fillText('d', d.x + 5, d.y + 5);

    // 6. Draw caption
    ctx.font = '20px SimHei';
    ctx.textAlign = 'center';
    ctx.fillText('习题 6－1 图', canvas.width / 2, canvas.height - 5);

</script>
</body>
</html>